package io.hellsinger.vortex.ui.component.trail

import android.content.Context
import android.content.res.ColorStateList
import android.graphics.drawable.RippleDrawable
import android.view.View
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.LinearLayout.LayoutParams.WRAP_CONTENT
import android.widget.TextView
import androidx.core.view.contains
import androidx.core.view.isVisible
import io.hellsinger.vortex.R
import io.hellsinger.vortex.data.model.PathItem
import io.hellsinger.vortex.ui.component.adapter.holder.RecyclableView
import io.hellsinger.vortex.ui.component.dp
import io.hellsinger.vortex.ui.component.drawable.RoundedCornerDrawable
import io.hellsinger.vortex.ui.icon.Icons

class TrailItemView(
    context: Context,
) : FrameLayout(context),
    RecyclableView<PathItem> {
    private val leftPadding = 8.dp
    private val rightPadding = 8.dp

    private val surface =
        RoundedCornerDrawable(
            color = 0,
            radius = 16F.dp,
        )

    var title: CharSequence?
        get() = titleView.text
        set(value) {
            if (value == titleView.text) return
            ensureContainingTitle()
            titleView.text = value
        }

    var isArrowVisible: Boolean
        get() = arrowView.isVisible
        set(value) {
            if (value == arrowView.isVisible) return
            ensureContainingArrow()
            arrowView.isVisible = value
        }

    init {
        id = R.id.file_manager_list_trail_item_root
        isClickable = true
        isFocusable = true
        background = surface
        foreground = createRippleForeground()
    }

    private val titleView =
        TextView(context).apply {
            layoutParams = LayoutParams(WRAP_CONTENT, WRAP_CONTENT)
            textSize = 16F
        }

    private val arrowView =
        ImageView(context).apply {
            layoutParams = LayoutParams(WRAP_CONTENT, WRAP_CONTENT)
            setImageDrawable(Icons.Rounded.ArrowRight)
        }

    private fun ensureContainingTitle() {
        if (!contains(titleView)) {
            addView(titleView)
        }
    }

    private fun ensureContainingArrow() {
        if (!contains(arrowView)) {
            addView(arrowView)
        }
    }

    override fun onBind(item: PathItem) {
//        title = item.name
    }

    override fun onBindSelection(isSelected: Boolean) {
        setSelected(isSelected)
    }

    override fun onBindPayload(payload: Any?) {
        if (payload is Boolean) {
            isArrowVisible = payload
        }
    }

    override fun onUnbind() {
        title = null
        isArrowVisible = false
    }

    override fun onBindListener(listener: OnClickListener?) {
        setOnClickListener(listener)
    }

    override fun onBindLongListener(listener: OnLongClickListener?) {
        setOnLongClickListener(listener)
    }

    override fun onUnbindListeners() {
        setOnClickListener(null)
        setOnLongClickListener(null)
    }

    fun setRippleColors(
        normal: Int,
        selected: Int,
    ) {
        (foreground as RippleDrawable).setColor(createStateList(normal, selected))
    }

    private fun createRippleForeground() =
        RippleDrawable(
            createStateList(),
            null,
            surface,
        )

    private fun createStateList(
        normal: Int = 0,
        selected: Int = 0,
    ): ColorStateList =
        ColorStateList(
            arrayOf(
                intArrayOf(android.R.attr.state_selected),
                intArrayOf(),
            ),
            intArrayOf(selected, normal),
        )

    override fun onMeasure(
        widthSpec: Int,
        heightSpec: Int,
    ) {
        var width = leftPadding + rightPadding
        val height = 40.dp

        if (!title.isNullOrEmpty()) {
            measureChild(
                titleView,
                widthSpec,
                heightSpec,
            )
            width += titleView.measuredWidth
        }

        if (arrowView.isVisible) {
            measureChild(
                arrowView,
                widthSpec,
                heightSpec,
            )
            width += arrowView.measuredWidth
        }

        setMeasuredDimension(width, height)
    }

    fun setTitleColors(
        normal: Int,
        selected: Int,
    ) = titleView.setTextColor(createStateList(normal, selected))

    fun setArrowColors(
        normal: Int,
        selected: Int,
    ) {
        arrowView.imageTintList = createStateList(normal, selected)
    }

    override fun setBackgroundColor(color: Int) {
        surface.setColor(color)
    }

    override fun onLayout(
        changed: Boolean,
        left: Int,
        top: Int,
        right: Int,
        bottom: Int,
    ) {
        var width = 0

        if (!title.isNullOrEmpty()) {
            width += leftPadding
            val padding = getVerticalPadding(titleView)
            titleView.layout(
                width,
                padding,
                width + titleView.measuredWidth,
                padding + titleView.measuredHeight,
            )
            width += titleView.measuredWidth
        }

        if (isArrowVisible) {
            width += leftPadding
            val padding = getVerticalPadding(arrowView)
            arrowView.layout(
                width,
                padding,
                width + arrowView.measuredWidth,
                padding + arrowView.measuredHeight,
            )
        }
    }

    private fun getVerticalPadding(view: View): Int = (height - view.measuredHeight) / 2

    private fun getHorizontalPadding(view: View): Int = (width - view.measuredWidth) / 2
}
